using Fiddler;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TangCaptureTraffic
{
    /// <summary>
    /// 会话辅助类，提供网络会话对象的格式化和处理功能
    /// </summary>
    public static class SessionHelper
    {
        /// <summary>
        /// 将Fiddler会话对象转换为详细的可读字符串格式
        /// </summary>
        /// <param name="session">要转换的Fiddler会话对象</param>
        /// <returns>包含会话详细信息的格式化字符串，如果会话为null则返回null</returns>
        public static string ToString(Session session)
        {
            // 检查会话对象是否为空
            if (session == null) return null;

            // 创建字符串构建器来组装会话信息
            StringBuilder sb = new StringBuilder();

            // 添加会话基本信息
            sb.AppendLine($"=== 会话 #{session.id} ===");
            sb.AppendLine($"请求方法: {session.RequestMethod}");
            sb.AppendLine($"请求URL: {session.fullUrl}");
            sb.AppendLine($"主机: {session.hostname}");
            sb.AppendLine($"状态码: {DisplayHelper.FormatStatusCode(session.responseCode)}");

            // 添加时间信息
            //if (session.Timers != null)
            //{
            //    sb.AppendLine($"请求时间: {DisplayHelper.FormatRequestTime(session.Timers.ClientConnected)}");
            //    var responseTime = (int)(session.Timers.ClientDoneResponse - session.Timers.ClientBeginRequest).TotalMilliseconds;
            //    sb.AppendLine($"响应时间: {DisplayHelper.FormatResponseTime(responseTime)}");
            //}

            // 添加响应信息
            var contentType = session.ResponseHeaders["Content-Type"];
            if (!string.IsNullOrEmpty(contentType))
            {
                sb.AppendLine($"内容类型: {DisplayHelper.SimplifyContentType(contentType)}");
            }

            if (session.ResponseBody != null)
            {
                sb.AppendLine($"响应大小: {DisplayHelper.FormatFileSize(session.ResponseBody.Length)}");
            }

            sb.AppendLine();

            // 添加请求头信息
            sb.AppendLine("=== 请求头 ===");
            foreach (var header in session.RequestHeaders)
            {
                sb.AppendLine($"{header.Name}: {header.Value}");
            }

            sb.AppendLine();

            // 添加请求体内容（如果有的话）
            var requestBody = session.GetRequestBodyAsString();
            if (!string.IsNullOrEmpty(requestBody))
            {
                sb.AppendLine("=== 请求体 ===");
                sb.AppendLine(requestBody);
                sb.AppendLine();
            }

            // 添加响应头信息
            sb.AppendLine("=== 响应头 ===");
            foreach (var header in session.ResponseHeaders)
            {
                sb.AppendLine($"{header.Name}: {header.Value}");
            }

            sb.AppendLine();

            // 添加响应体内容（限制长度以避免界面卡顿）
            var responseBody = session.GetResponseBodyAsString();
            if (!string.IsNullOrEmpty(responseBody))
            {
                sb.AppendLine("=== 响应体 ===");
                if (responseBody.Length > 5000)
                {
                    sb.AppendLine(responseBody.Substring(0, 5000));
                    sb.AppendLine($"\n... (响应体过长，已截断，完整长度: {responseBody.Length} 字符)");
                }
                else
                {
                    sb.AppendLine(responseBody);
                }
            }

            // 返回组装好的字符串
            return sb.ToString();
        }


        /// <summary>
    /// 获取会话的请求信息文本，包括请求头和请求体
    /// </summary>
    /// <param name="session">要转换的Fiddler会话对象</param>
    /// <returns>包含会话请求详细信息的格式化字符串，如果会话为null则返回null</returns>
    public static string GetRequestText(Session session)
    {
        // 检查会话对象是否为空
        if (session == null) return null;

        // 创建字符串构建器来组装会话信息
        StringBuilder sb = new StringBuilder();

        // 添加会话基本信息
        sb.AppendLine($"=== 会话 #{session.id} ===");
        sb.AppendLine($"请求方法: {session.RequestMethod}");
        sb.AppendLine($"请求URL: {session.fullUrl}");
        sb.AppendLine($"主机: {session.hostname}");
        sb.AppendLine($"状态码: {DisplayHelper.FormatStatusCode(session.responseCode)}");

        // 添加时间信息
        //if (session.Timers != null)
        //{
        //    sb.AppendLine($"请求时间: {DisplayHelper.FormatRequestTime(session.Timers.ClientConnected)}");
        //    var responseTime = (int)(session.Timers.ClientDoneResponse - session.Timers.ClientBeginRequest).TotalMilliseconds;
        //    sb.AppendLine($"响应时间: {DisplayHelper.FormatResponseTime(responseTime)}");
        //}

        // 添加响应信息
        var contentType = session.ResponseHeaders["Content-Type"];
        if (!string.IsNullOrEmpty(contentType))
        {
            sb.AppendLine($"内容类型: {DisplayHelper.SimplifyContentType(contentType)}");
        }

        if (session.ResponseBody != null)
        {
            sb.AppendLine($"响应大小: {DisplayHelper.FormatFileSize(session.ResponseBody.Length)}");
        }

        sb.AppendLine();

        // 添加请求头信息
        sb.AppendLine("=== 请求头 ===");
        foreach (var header in session.RequestHeaders)
        {
            sb.AppendLine($"{header.Name}: {header.Value}");
        }

        sb.AppendLine();

        // 添加请求体内容（如果有的话）
        var requestBody = session.GetRequestBodyAsString();
        if (!string.IsNullOrEmpty(requestBody))
        {
            sb.AppendLine("=== 请求体 ===");
            sb.AppendLine(requestBody);
            sb.AppendLine();
        }
        // 返回组装好的字符串
        return sb.ToString();
    }

        /// <summary>
        /// 获取会话的响应信息文本，包括响应头和响应体
        /// </summary>
        /// <param name="session">要转换的Fiddler会话对象</param>
        /// <returns>包含会话响应详细信息的格式化字符串，如果会话为null则返回null</returns>
        public static string GetResponseText(Session session)
        {
            // 检查会话对象是否为空
            if (session == null) return null;
            var sb = new StringBuilder();

            // 添加响应头信息
            sb.AppendLine("=== 响应头 ===");
            foreach (var header in session.ResponseHeaders)
            {
                sb.AppendLine($"{header.Name}: {header.Value}");
            }

            sb.AppendLine();

            // 添加响应体内容（限制长度以避免界面卡顿）
            var responseBody = session.GetResponseBodyAsString();
            if (!string.IsNullOrEmpty(responseBody))
            {
                sb.AppendLine("=== 响应体 ===");

                sb.AppendLine(responseBody);
            }
            // 返回组装好的字符串
            return sb.ToString();
        }
        /// <summary>
        /// 获取会话的Curl命令文本，包括请求头、请求体和URL
        /// </summary>
        /// <param name="session">要转换的Fiddler会话对象</param>
        /// <returns>包含会话Curl命令详细信息的格式化字符串，如果会话为null则返回null</returns>
        public static string GetcUrl(Session session)
        {
            var sb = new StringBuilder();
            sb.AppendLine($"curl \"{session.fullUrl}\"");
            foreach (var header in session.RequestHeaders)
            {
                sb.AppendLine($"-H \"{header.Name}: {header.Value}\"");
            }
            if (session.RequestBody != null)
            {
                sb.AppendLine($"-d \"{session.GetRequestBodyAsString()}\"");
            }
            return sb.ToString();
        }

        /// <summary>
        /// 重发会话请求，使用原始会话的请求头和请求体创建一个新的请求
        /// </summary>
        /// <param name="session">要重发的会话对象</param>
        /// <returns>如果重发成功返回true，否则返回false</returns>
        public static Session ReSend(Session session)
        {
            if (session == null) return null;
            
            try
            {
                // 创建一个字典来存储额外的会话标志
                var sessionFlags = new System.Collections.Specialized.StringDictionary();
                sessionFlags.Add("X-ResentRequest", "true");
                
                // 使用FiddlerApplication.oProxy.SendRequestAndWait方法重发请求
                // 参数包括：原始请求头、请求体字节、会话标志和超时时间
                Session newSession = FiddlerApplication.oProxy.SendRequestAndWait(
                    session.oRequest.headers,    // 原始请求头
                    session.requestBodyBytes,    // 原始请求体
                    sessionFlags,                // 会话标志
                    null                         // 使用默认超时时间
                );
                
                // 检查新会话是否创建成功
                return newSession;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"重发请求时发生错误: {ex.Message}");
                return null;
            }
        }

    }
}
